﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using AI_Game;
using System.Diagnostics;

namespace AI_GAME
{
    public partial class Ban_AI : UserControl
    {
        public Graphics g;// đối tượng để vẽ lên
        int cellSize; //kich cỡ 1 ô
        int rows, cols; //số dòng và số cột
        int[,] Data; // mảng 2 chiều lưu giá trị của 1 ô
        bool isPainted = false;
        Thread myAI;
        GodAI beyonGodAI, beyonGodAI2;

        int x1Old, y1Old;
        int x2Old, y2Old; 

        /// <summary>
        /// xác đinh lượt đánh 
        /// true là O đánh
        /// false là X đánh
        /// </summary>
        bool flag;
        public Ban_AI(int cellSize, int rows, int cols, bool flag)
        {
            InitializeComponent();// hàm mặc đinh để khỏi tạo một đối tượng control      

            //-- Đưa dữ liệu vào cho các trường
            this.cellSize = cellSize;
            this.rows = rows;
            this.cols = cols;
            this.flag = flag;
            //--

            //--- Khỏi tạo giá trị mặc định cho các ô là 0
            Data = new int[rows, cols];
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < cols; j++)
                    Data[i, j] = 0;
            //---               
        }
        /// <summary>
        /// Hàm sẻ vẽ các đường thẳng và đường ngang khi đối tượng được khỏi tạo
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Ban_Paint(object sender, PaintEventArgs e)
        {
            if (!isPainted)
            {
                isPainted = true;
                Width = cols * cellSize + 1; // tạo chiều rộng cho bàn 
                Height = rows * cellSize + 1;// tạo chiều cao cho bàn;

                g = this.CreateGraphics();
                int i, j;
                Pen p = new Pen(Color.Blue);
                for (i = 0; i <= rows; i++)
                    g.DrawLine(p, 0, i * cellSize, rows * cellSize, i * cellSize);

                for (j = 0; j <= cols; j++)
                    g.DrawLine(p, j * cellSize, 0, j * cellSize, cols * cellSize);

                RandomBlackCell(4);
                StartMatch();
            }
        }
        /// <summary>
        /// Vẽ X
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private void Ve_X(int x, int y)
        {
            Pen p = new Pen(Color.Black, 5);
            //Vẽ chéo thuận
            g.DrawLine(p, x * cellSize, y * cellSize, (x + 1) * cellSize, (y + 1) * cellSize);
            // Vẽ chéo nghịch
            g.DrawLine(p, (x + 1) * cellSize, y * cellSize, x * cellSize, (y + 1) * cellSize);
        }
        /// <summary>
        /// Vẽ O
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private void Ve_O(int x, int y)
        {
            Pen p = new Pen(Color.Blue, 5);
            g.DrawEllipse(p, x * cellSize + 2, y * cellSize + 2, cellSize - 5, cellSize - 5);
        }

        private void FillBlackCell(int x, int y) 
        {
            SolidBrush blueBrush = new SolidBrush(Color.Black);
            g.FillRectangle(blueBrush, x * cellSize + 1, y * cellSize + 1, cellSize - 1, cellSize - 1);
        }

        private void FillRedCell(int x, int y)
        {
            SolidBrush blueBrush = new SolidBrush(Color.Red);
            g.FillRectangle(blueBrush, x * cellSize + 1, y * cellSize + 1, cellSize - 1, cellSize - 1);
        }

        private void FillDarkRedCell(int x, int y) 
        {
            SolidBrush blueBrush = new SolidBrush(Color.DarkRed);
            g.FillRectangle(blueBrush, x * cellSize + 1, y * cellSize + 1, cellSize - 1, cellSize - 1);
        }

        private void RandomBlackCell(int Number)
        {
            for (int i = 0; i < Number; i++)
            {
                Random r = new Random();
                while (true)
                {
                    int x = r.Next(0, 6);
                    int y = r.Next(0, 6);
                    if ((x != 0 || y != 0) &&
                        (x != 10 || y != 10) &&
                        (x != 5 || y != 5) &&
                        (x > 2 || y > 2) &&
                        (Data[x, y] == 0))
                    {
                        Data[x, y] = 1;
                        FillBlackCell(x, y);

                        Data[10 - x, 10 - y] = 1;
                        FillBlackCell(10 - x, 10 - y);

                        break;
                    }
                }
            }
        }
        public void StartMatch()
        {
            Data[0, 0] = 2;
            FillRedCell(0, 0);
            x1Old = 0;
            y1Old = 0;

            Data[10, 10] = 2;
            FillRedCell(10, 10);
            x2Old = 10;
            y2Old = 10;

            beyonGodAI = new GodAI(Data, 0, 0);
            beyonGodAI2 = new GodAI(Data, 10, 10);
           

            Thread.Sleep(2000); 
            myAI = new Thread(AI);
            myAI.Start();
        }
        public void AI()
        {
            while (true)
            {
                //flag = false;
                if (!flag)
                {
                    flag = true;
                    //Random r = new Random();
                    //while (true)
                    //{
                    //    int x = r.Next(0, cols);
                    //    int y = r.Next(0, rows);
                    //    if (Data[x, y] == 0) // nếu ô này chưa đc đánh
                    //    {
                    //        Data[x, y] = 2;
                    //        FillRedCell(x, y);
                    //        break;
                    //    }
                    //}
                    beyonGodAI.FindLine();
                    int x = 0, y = 0;
                    beyonGodAI.Go(ref x, ref y);
                    Data[x, y] = 2;

                    FillDarkRedCell(x1Old, y1Old);
                    FillRedCell(x, y);
                    x1Old = x;
                    y1Old = y;
                    Thread.Sleep(200);
                }
            }
            /*beyonGodAI.FindLine();
            int countALine = 0;
            int[] GoLine = beyonGodAI.GetLine(ref countALine);
            int x = 0, y = 0;
            for (int i = 1; i < countALine; i++)
            {
                //Trace.WriteLine("GoLine["+i.ToString()+"] =" + GoLine[i].ToString());
                x = GoLine[i] % 11;
                y = GoLine[i] / 11;
                if (Data[x, y] == 0)
                {
                    Data[x, y] = 2;
                    FillRedCell(x, y);
                    Thread.Sleep(200);
                }
                else
                {
                    break;
                }
            }*/

        }

        /// <summary>
        /// Làm việc khi nhấn chuột lên các ô của bàn
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Ban_MouseDown(object sender, MouseEventArgs e)
        {
            int x = e.X / cellSize;// lấy số dòng
            int y = e.Y / cellSize; // lấy số cột
            StartAI2(x, y);
          
        }
        private void StartAI2(int x, int y)
        {
            AI2(x, y);
        }
        private void AI2(int x, int y)
        {
            int xGo, yGo;
            xGo = x2Old;
            yGo = y2Old;

            int countAMinLine = 0;
            int[] aMinLine;

            aMinLine = beyonGodAI2.FindLine2(xGo, yGo, x, y, ref countAMinLine);

            int i = 0;

            while ((xGo != x || yGo != y) && i < countAMinLine )
            {
                if (flag)
                {
                    /*if (Data[x, y] == 0) // nếu ô này chưa đc đánh
                    {
                        Data[x, y] = 2;
                        FillDarkRedCell(x2Old, y2Old);
                        FillRedCell(x, y);
                        x2Old = x;
                        y2Old = y;
                        flag = false;
                    }*/
                    flag = false;
                    i++;
                    xGo = aMinLine[i] % 11;
                    yGo = aMinLine[i] / 11;


                    Data[xGo, yGo] = 2;
                    FillDarkRedCell(x2Old, y2Old);
                    FillRedCell(xGo, yGo);
                    x2Old = xGo;
                    y2Old = yGo;
                    Thread.Sleep(200);
                }
            }
        }
    }
}
